package cn.lg.soar.core.util.easyexcel;

import cn.lg.soar.common.util.DatetimeUtil;
import cn.lg.soar.core.util.easyexcel.model.CellInfo;
import cn.lg.soar.core.util.easyexcel.model.MergeCellInfo;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellAddress;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * poi 工具
 * @author luguoxiang
 * @date 2021-06-18
 * @Dep: excel 工具
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public interface PoiExcelUtil {

    /**
     * 设置单元格（存在设置值，不存在创建）
     * @param sheet
     * @param cellInfo
     */
    static void setCell(Sheet sheet, CellInfo cellInfo) {
        int rowIndex = cellInfo.getRowIndex();
        Row row = sheet.getRow(rowIndex);
        if (row == null) {
            row = sheet.createRow(rowIndex);
        }
        int colIndex = cellInfo.getColIndex();
        Cell cell = row.getCell(colIndex);
        if (cell == null) {
            cell = row.createCell(colIndex);
        }
        Object value = cellInfo.getValue();
        if (value != null) {
            cell.setCellValue(value.toString());
        }
        cell.setCellStyle(cellInfo.getStyle());
    }

    /**
     * 设置合并单元格（存在设置值，不存在创建）
     * @param sheet
     * @param cellInfo
     */
    static void setMergeCell(Sheet sheet, MergeCellInfo cellInfo) {
        setCell(sheet, cellInfo);
        if (cellInfo.isMerge()) {
            sheet.addMergedRegionUnsafe(cellInfo.getCellRangeAddress());
        }
    }

    /**
     * 设置单元格值
     * @param cell
     * @return
     */
    static void setCellValue(Cell cell, Object value) {
        if (value instanceof String) {
            cell.setCellValue((String) value);
            return;
        }
        if (value instanceof Number) {
            cell.setCellValue(Double.parseDouble(value.toString()));
            return;
        }
        if (value instanceof Boolean) {
            cell.setCellValue((Boolean) value);
            return;
        }
        if (value instanceof LocalDateTime) {
            cell.setCellValue((LocalDateTime) value);
            return;
        }
        if (value instanceof LocalDate) {
            cell.setCellValue((LocalDate) value);
            return;
        }
        if (value instanceof Date) {
            cell.setCellValue((Date) value);
            return;
        }
        if (value == null) {
            return;
        }
        cell.setCellValue(value.toString());
    }

    /**
     * 获取单元格值
     * @param cell
     * @return
     */
    static Object getCellValue(Cell cell) {
        switch (cell.getCellType()) {
            case STRING: return cell.getStringCellValue();
            case NUMERIC: return cell.getNumericCellValue();
            case BOOLEAN: return cell.getBooleanCellValue();
            case FORMULA: return cell.getCellFormula();
            default: return null;
        }
    }

    /**
     * 获取单元格值
     * @param cell
     * @return
     */
    static BigDecimal getBigDecimalValue(Cell cell) {
        switch (cell.getCellType()) {
            case BOOLEAN: throw new IllegalStateException(String.format("无法把%s转数值", cell.getBooleanCellValue()));
            case NUMERIC: return BigDecimal.valueOf(cell.getNumericCellValue());
            case STRING: return new BigDecimal(cell.getStringCellValue());
            case FORMULA:
                try {
                    return BigDecimal.valueOf(cell.getNumericCellValue());
                } catch (RuntimeException e) {

                }
                try {
                    return new BigDecimal(cell.getStringCellValue());
                } catch (RuntimeException e) {
                    throw e;
                }
            default:
                return null;
        }
    }

    /**
     * 获取单元格值
     * @param cell
     * @return
     */
    static Long getLongValue(Cell cell) {
        switch (cell.getCellType()) {
            case BOOLEAN: throw new IllegalStateException(String.format("无法把%s转数值", cell.getBooleanCellValue()));
            case NUMERIC: return ((Double) cell.getNumericCellValue()).longValue();
            case STRING: return Long.valueOf(cell.getStringCellValue());
            case FORMULA:
                try {
                    return ((Double) cell.getNumericCellValue()).longValue();
                } catch (RuntimeException e) {

                }
                try {
                    return Long.valueOf(cell.getStringCellValue());
                } catch (RuntimeException e) {
                    throw e;
                }
            default:
                return null;
        }
    }

    /**
     * 获取单元格值
     * @param cell
     * @return
     */
    static String getStringValue(Cell cell) {
        switch (cell.getCellType()) {
            case BOOLEAN: return String.valueOf(cell.getBooleanCellValue());
            case NUMERIC: return String.valueOf(cell.getNumericCellValue());
            case STRING: return cell.getStringCellValue();
            case FORMULA:
                try {
                    return cell.getStringCellValue();
                } catch (RuntimeException e) {

                }
                try {
                    return String.valueOf(cell.getNumericCellValue());
                } catch (RuntimeException e) {

                }
                try {
                    return String.valueOf(cell.getBooleanCellValue());
                } catch (RuntimeException e) {

                }
            default:
                return null;
        }
    }

    /**
     * 获取单元格值
     * @param cell
     * @return
     */
    static Boolean getBooleanValue(Cell cell) {
        switch (cell.getCellType()) {
            case BOOLEAN: cell.getBooleanCellValue();
            case NUMERIC: throw new IllegalStateException(String.format("无法把%s转布尔值", cell.getBooleanCellValue()));
            case STRING: return Boolean.valueOf(cell.getStringCellValue());
            case FORMULA:
                try {
                    return cell.getBooleanCellValue();
                } catch (RuntimeException e) {

                }
                try {
                    return Boolean.valueOf(cell.getStringCellValue());
                } catch (RuntimeException e) {
                    throw e;
                }
            default:
                return null;
        }
    }

    /**
     * 获取单元格值
     * @param cell
     * @return
     */
    static LocalDateTime getLocalDateTimeValue(Cell cell) {
        try {
            return cell.getLocalDateTimeCellValue();
        } catch (RuntimeException e) {
            return DatetimeUtil.from(cell.getStringCellValue());
        }
    }

}
